package cn.hashq.netpostclient.handler.proxy;

import cn.hashq.netpostclient.dto.ProtoMsg;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@ChannelHandler.Sharable
public class HeartBeatHandler extends ChannelInboundHandlerAdapter {

    private final long HEARTBEAT_INTERVAL = 50;

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("heart beat active");
        // 定时发送心跳
        ProtoMsg.HeartBody heartBody = ProtoMsg.HeartBody.newBuilder().setBody("keep alive").build();
        ProtoMsg.Message msg = ProtoMsg.Message.newBuilder()
                .setType(ProtoMsg.HeadType.HEART_BEAT)
                .setSequence(0).setHeart(heartBody).build();
        heartBeat(ctx, msg);
    }

    private void heartBeat(ChannelHandlerContext ctx, ProtoMsg.Message msg) {
        ctx.executor().schedule(() -> {
            if (ctx.channel().isActive()) {
                ctx.channel().writeAndFlush(msg);
                heartBeat(ctx, msg);
            }
        }, HEARTBEAT_INTERVAL, TimeUnit.SECONDS);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (Objects.isNull(msg) || !(msg instanceof ProtoMsg.Message)) {
            super.channelRead(ctx, msg);
            return;
        }
        ProtoMsg.Message pkg = (ProtoMsg.Message) msg;
        ProtoMsg.HeadType type = pkg.getType();
        if (!type.equals(ProtoMsg.HeadType.HEART_BEAT)) {
            super.channelRead(ctx, msg);
            return;
        }
        log.info("keep alive");
    }
}
